#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include "compute.h"
#include "tasks.h"


/** <IMPLEMENTATION> **/

void s1_task(unsigned int id, iface_t* bw_if, iface_t* fw_if) {
  FILE* in;
  FILE* out;
  size_t size;

  bw_if = NULL; /* To calm the compiler down */

  /* Open files again */
  in = fopen(in_path, "rb");
  if (in == NULL) {
    err(EXIT_FAILURE, ERR_FOPEN_R);
  }
  out = fopen(out_path, "r+b");
  if (out == NULL) {
    err(EXIT_FAILURE, ERR_FOPEN_W);
  }
  /* Seek to initial position for this task */
  if ( (fseek(in,  id*blocksize, SEEK_SET) != 0) ||
       (fseek(out, id*blocksize, SEEK_SET) != 0) ) {
    return;
  }

  /* Process */
  do {
    unsigned char b[blocksize];
    unsigned int j;

    /* Read block */
    size = fread(b, 1, blocksize, in);
    if (size <= 0)
      break;

    /* Apply XOR */
    for (j = 0; j < size; ++j) {
      b[j] ^= mask;
    }

    /* Write to pipe and output file */
    write(fw_if->w_pipes[id], b, size);
    fwrite(b, size, 1, out);

  } while ( (fseek(in,  (p1 - 1) * blocksize, SEEK_CUR) == 0) &&
            (fseek(out, (p1 - 1) * blocksize, SEEK_CUR) == 0) );
} /* END OF: s1_task() */


void s2_task(unsigned int id, iface_t* bw_if, iface_t* fw_if) {
  unsigned int i;
  unsigned char msg;  /* Holds the dummy synch-message from main */

  i = id % p1;
  while (read(fw_if->r_pipes[id], &msg, 1) > 0) {
    unsigned char b[blocksize]; /* Holds a block fetched from stage 1 */
    size_t size;
    unsigned int j;
    unsigned int sum;

    /* Fetch a block */
    size = read(bw_if->r_pipes[i], b, blocksize);
    if (size <= 0)
      break;

    /* Calculate the sum */
    for (sum = 0, j = 0; j < size; ++j) {
      sum += b[j];
    }

    /* Print sum and send to main */
    printf("%u ", sum); fflush(stdout);
    write(fw_if->w_pipes[id], &sum, sizeof(sum));

    /* Update index of the next pipe to read block from */
    i = (i + p2) % p1;
  }
} /* END OF: s2_task() */

/** </IMPLEMENTATION> **/

